﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using System.Drawing.Imaging;
using System.Drawing;

namespace WatCD
{
    public class CircleAnalysis
    {
        private string _fileName;
        public CircleAnalysis(string fileName)
        {
            _fileName = fileName;
        }

        public int WatCD()
        {
            //Load the image from file
            Image<Bgr, Byte> img = new Image<Bgr, byte>(_fileName).Resize(400, 400, Emgu.CV.CvEnum.INTER.CV_INTER_LINEAR, true);

            //Convert the image to grayscale and filter out the noise
            Image<Gray, Byte> gray = img.Convert<Gray, Byte>().PyrDown().PyrUp();

            //Adjust Brightness
            Bitmap originalImage = gray.ToBitmap();          

            Gray cannyThreshold = new Gray(180);
            Gray cannyThresholdLinking = new Gray(120);
            Gray circleAccumulatorThreshold = new Gray(120);

            CircleF[] circles = gray.HoughCircles(
                cannyThreshold,
                circleAccumulatorThreshold,
                2.0, //Resolution of the accumulator used to detect centers of the circles
                20.0, //min distance
                20, //min radius
                0 //max radius
                )[0]; //Get the circles from the first channel

            float step = 0.5f;
            while (circles.Length > 1)
            {
                Bitmap newImg = this.DecreaseBrightness(originalImage, step);
                Image<Bgr, Byte> Nimg = new Image<Bgr, byte>(newImg);

                gray = Nimg.Convert<Gray, Byte>();//.PyrDown().PyrUp();
                circles = gray.HoughCircles(
                cannyThreshold,
                circleAccumulatorThreshold,
                2.0, //Resolution of the accumulator used to detect centers of the circles
                20.0, //min distance
                20, //min radius
                0 //max radius
                )[0]; //Get the circles from the first channel

                step = step + 0.1f;
            }

            if (circles.Length == 0)
            {               
                return 0;
            }

            return Convert.ToInt32(circles[0].Radius) * 2;
        }

        private Bitmap DecreaseBrightness(Bitmap original, float decreaseStep)
        {
            Bitmap originalImage = original;
            Bitmap adjustedImage = new Bitmap(original.Width, original.Height);
            float brightness = 1.0f;
            float contrast = 1.0f;
            float gamma = 1.0f;

            float adjustedBrightness = brightness - decreaseStep;
            // create matrix that will brighten and contrast the image
            float[][] ptsArray ={
            new float[] {contrast, 0, 0, 0, 0}, // scale red
            new float[] {0, contrast, 0, 0, 0}, // scale green
            new float[] {0, 0, contrast, 0, 0}, // scale blue
            new float[] {0, 0, 0, 1.0f, 0}, // don't scale alpha
            new float[] {adjustedBrightness, adjustedBrightness, adjustedBrightness, 0, 1}};

            ImageAttributes imageAttributes = new ImageAttributes();
            imageAttributes.ClearColorMatrix();
            imageAttributes.SetColorMatrix(new ColorMatrix(ptsArray), ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
            imageAttributes.SetGamma(gamma, ColorAdjustType.Bitmap);
            Graphics g = Graphics.FromImage(adjustedImage);
            g.DrawImage(originalImage, new Rectangle(0, 0, adjustedImage.Width, adjustedImage.Height)
                , 0, 0, originalImage.Width, originalImage.Height,
                GraphicsUnit.Pixel, imageAttributes);

            return adjustedImage;
        }
    }
}
